﻿
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Agrement;
using analy;
using System.Threading.Tasks;
using System.Net.Http;
using System.Web.Script.Serialization;
namespace SockLib.Device
{
    class ModBus:IDevice 
    {

        /// <summary>
        /// 外部传进来的参数
        /// </summary>
        Dictionary<string, object> Par = new Dictionary<string, object>();
        public void SetParars(Dictionary<string, object> Params)
        {
            Par = Params;
        }
        JavaScriptSerializer JS = new JavaScriptSerializer();
        #region 注册处理
        /// <summary>
        /// 收到数据是否满足注册条件
        /// </summary>
        /// <param name="Buffer">Socket收到的数据</param>
        /// <param name="DM">如果成功解析，DM写入相应信息</param>
        /// <returns>True：成功解析，False：未能解析（乱数据）</returns>
        public bool DeviceReg(byte[] Buffer, ref DeviceModel DM, out List<DeviceModel.SendMsg> Sendinfo)
        {
            try
            {
                Sendinfo = new List<DeviceModel.SendMsg>();
                DeviceModel DeviceModel = new DeviceModel();
                MODBUS_MODEL  RegMsg;            
                if (!RegRull(Buffer, out  RegMsg))
                {
                    return false  ;  //未能解析，返回失败
                }                 
                DeviceModel.Uid = RegMsg.gprs_code ;
                DeviceModel.DeviceGroup = DeviceModel.Uid.Substring(1, 4); //获取组号
                DeviceModel.MobileNo = RegMsg.phone;  //获得手机号
                DM = DeviceModel;
                DeviceModel.SendMsg DS = new DeviceModel.SendMsg();
                DS.TargetUid = DeviceModel.Uid;
                DS.DeviceOper = Converts.DeviceOper.Register;
                DS.SendBuffer = System.Text.Encoding.Default.GetBytes(JS.Serialize(RegMsg));
                if (Convert.ToInt16(DeviceModel.Uid.Substring(0, 1)) == 1)  //第1位是1中心，其他节点
                {
                    DeviceModel.IsCenter = true;

                    Sendinfo.Add(DS);
                }
                else
                    DeviceModel.IsCenter = false;
           
                return true;   //返回注册成功
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }


        /// <summary>
        /// 这是一个modbus设备
        /// </summary>
        /// <returns></returns>
        public string DeviceType()
        {
            if (devicetype == "modbuscenter")
                return "Modbus采集器";
            else
                return "Modbus控制器";
        }

         string devicetype = "modbuscenter";

        /// <summary>
        /// 验证是否能注册
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        private bool ReadKey(string key)
        {
            devicetype = key;
            //modbuscenter和debug不验证有效性
            if (key == "modbuscenter" || key == "debug")
                return true;
            DataBaseApi.API api = new DataBaseApi.API();
            return api.IsRegisters(key);
            //return true;
        }

        /// <summary>
        /// <para>身份信息验证</para>
        /// </summary>
        /// <param name="Buffer">SOCKET接收到的数据</param>
        /// <param name="reg">JSON反序列得到的对象</param>
        /// <returns></returns>
        private bool RegRull(byte[] Buffer, out MODBUS_MODEL reg)
        {
            reg = new MODBUS_MODEL();
            try
            {

                List<byte[]> RegList = new List<byte[]>();
                RegList = GetJson(Buffer);
                if (RegList.Count > 0)
                {
                    foreach (byte[] msg in RegList)
                    {
                        string rec = System.Text.Encoding.Default.GetString(msg);
                        MODBUS_MODEL MM = JS.Deserialize<MODBUS_MODEL>(rec);
                        if ((MM.gprs_code == null) || (MM.phone == null)|| (MM.user_key  == null)|| MM.gprs_code.Length <8|| MM.gprs_code.Length>11)
                        {
                            return false;
                        }
                        else
                        {
                            if (MM.flag != 0)
                                return false;
                        }
                        if (!ReadKey(MM.user_key))  //需要验证
                            return false;
                        reg = MM;
                    }
                   
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                logexception.WriteLogToFile(ex);
                string msg = ex.Message;
                return false;
            }
        }

        /// <summary>
        /// 收到byte[]中，把{}中的数据变成list<byte[]>中一项
        /// </summary>
        /// <param name="reg">注册的数组</param>
        /// <returns></returns>
        private List<byte[]> GetJson(byte[] reg)
        {
            List<byte> ReadJson = new List<byte>();
            ReadJson.AddRange(reg);
            List<byte[]> RetJson = new List<byte[]>();
            while (ReadJson.Count > 0)
            {
                int StartCharInt = 0;
                int EndCharInt = 0;
                if (ReadJson[0] == 0x7b)
                {
                    List<byte> readbyte = new List<byte>();
                    int RemoveCount = 0;
                    for (int i = 0; i < ReadJson.Count; i++)
                    {
                        if (ReadJson[i] == 0x7b)
                            StartCharInt += 1;
                        if (ReadJson[i] == 0x7d)
                            EndCharInt += 1;
                        readbyte.Add(ReadJson[i]);
                        if (StartCharInt == EndCharInt)
                        {
                            RetJson.Add(readbyte.ToArray());
                            ReadJson.RemoveRange(0, i);
                            RemoveCount = i;
                            break;
                        }
                    }
                    if (RemoveCount == 0)
                        ReadJson.RemoveAt(0);
                }
                else
                    ReadJson.RemoveAt(0);
            }
            return RetJson;
        }
        #endregion


        #region 获取数据转发结构
        /// <summary>
        /// 中心数据转发规则,数据发送给节点
        /// </summary>
        /// <param name="ReceiveData"></param>
        public bool TransferRule(byte[] ReceiveData, out List<DeviceModel.SendMsg> Sendinfo)
        {
            Sendinfo = new List<DeviceModel.SendMsg>();
            List<byte[]> JSONSTR = new List<byte[]>();
            JSONSTR= GetJson(ReceiveData);
            foreach (byte[]  msg in JSONSTR )
            {              
                string rec = System.Text.Encoding.Default.GetString(msg);
                MODBUS_MODEL MM = JS.Deserialize<MODBUS_MODEL>(rec);
                if (MM.gprs_code == null || MM.modbus_msg == null)
                {
                    continue;
                }
                DeviceModel.SendMsg DS = new Device.DeviceModel.SendMsg();
                DS.TargetUid = MM.gprs_code;
                DS.SendBuffer = MM.modbus_msg;
                DS.DeviceOper = Converts.DeviceOper.Transfer;
                Sendinfo.Add(DS);
            }
       
            if (Sendinfo.Count > 0)
                return true;
            else
                return false;
        }


        /// <summary>
        /// 节点数据转发规则,数据发送给中心
        /// </summary>
        /// <param name="ReceiveData">收到的数据</param>
        /// <param name="uid">GPRS的编号</param>
        /// <param name="Sendinfo">需要转发的结构体</param>
        /// <returns></returns>
        public bool NodeTransferRule(byte[] ReceiveData, string uid, ref DeviceModel.SendMsg[] Sendinfos)
        {
            List<DeviceModel.SendMsg> LDS = new List<DeviceModel.SendMsg>();
            MODBUS_MODEL MM = new Device.MODBUS_MODEL();
            MM.gprs_code = uid;
            MM.modbus_msg = ReceiveData;
            MM.flag = 2;
            Device.DeviceModel.SendMsg Sendinfo = new Device.DeviceModel.SendMsg();
            Sendinfo.TargetUid = uid;
            Sendinfo.SendBuffer = System.Text.Encoding.Default.GetBytes(JS.Serialize(MM));
            Sendinfo.DeviceOper = Converts.DeviceOper.Transfer;
            LDS.Add(Sendinfo);
            Sendinfos = LDS.ToArray();
            return true;
        }

        #endregion


        #region 数据转换

        /// <summary>
        /// 心跳包格式
        /// </summary>
        /// <param name="TargetUid">发给的中心模块ID</param>
        /// <param name="uid">在线中心模块ID集合</param>
        /// <returns></returns>
       public  List< byte[]> HeartBeatConvert(string TargetUid, string[] uid)
        {
            if (devicetype  == "modbuscenter")
                return null;
            JSON_HEARTBEAT JH = new JSON_HEARTBEAT();
            JH.targetuid = TargetUid;
            JH.uid = uid;
            string s = JS.Serialize(JH);
            List<byte[]> LB = new List<byte[]>();
            LB.Add(System.Text.Encoding.Default.GetBytes(s));
            return LB;
            //List<byte[]> L = new List<byte[]>();
            //byte[] b = new byte[] { 0x2b };
            //L.Add(b);
            //return L;
        }


        /// <summary>
        /// 发送数据转换
        /// </summary>
        /// <param name="Data"></param>
        /// <returns></returns>
        public byte[] SendDataConvert(byte[] Data)
        {
            return Data;
        }

        /// <summary>
        /// 接收数据转换
        /// </summary>
        /// <param name="Data"></param>
        /// <returns></returns>
        public byte[] ReceiveDataConvert(byte[] Data)
        {
            return Data;
        }

        public byte[] DataPacket(DeviceModel.SendMsg SendMsg)
        {
            return SendMsg.SendBuffer;
        }
        #endregion



        #region 心跳包处理
        /// <summary>
        /// 心跳包不做任何转发处理
        /// </summary>
        /// <param name="?"></param>
        /// <returns></returns>
        public bool IsHeartPack(byte[] Pack)
        {
            if (Pack.Length == 1 && (Pack[0] == 0x2B || Pack[0] == 0xfe))
                return true;
            return false;

            //string rec = System.Text.Encoding.Default.GetString(Pack );
            //MODBUS_MODEL MM = JS.Deserialize<MODBUS_MODEL>(rec);
            //if (MM.gprs_code != null && MM.modbus_msg == null && MM.flag == 0 && MM.phone!=null )
            //    return true;
            //return false;
        }
        #endregion

        #region 显示LOG区发送数据
        public string SendString(string uid, byte[] msg)
        {
            if (uid.Substring(0, 1) == "1")
                return System.Text.Encoding.Default.GetString(msg);
            else
                return Converts.byteToHexStr(msg);
        }
        #endregion 
    }
}
